package com.project;

import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;

import static com.project.JDBCProperties.*;
import static com.project.NameUtils.packageConvertPath;
import static com.project.Resources.getData;


/**
 * 代码生成器，根据数据表名称生成对应的Model、Mapper、Service、Controller简化开发。
 */
public class ManageCodeGenerator {

    public static void main(String[] args) {
        try {
            genCode("fresh_order"
            );

            // getVueCode("member", "resume");
        } catch (IOException | TemplateException e) {
            e.printStackTrace();
        }
    }

    private static void getVueCode(String... tableNames) throws IOException, TemplateException {
        Configuration cfg = getConfiguration(TEMPLATE_FILE_PATH);
        for (String tableName : tableNames) {
            Map<String, Object> data = getData(tableName);
            String modelNameUpperCamel = data.get("modelNameUpperCamel").toString();
            getVueTable(cfg, data, modelNameUpperCamel);
            getVueFrom(cfg, data, modelNameUpperCamel);
            getVueUpdate(cfg, data, modelNameUpperCamel);
            getVueAdd(cfg, data, modelNameUpperCamel);
            getVueJs(cfg, data, modelNameUpperCamel);
        }
        try {
            java.awt.Desktop.getDesktop().open(new File(PACKAGE_PATH_VUE));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过数据表名称生成代码，Model 名称通过解析数据表名称获得，下划线转大驼峰的形式。
     * 如输入表名称 "t_user_detail" 将生成 TUserDetail、TUserDetailMapper、TUserDetailService ...
     *
     * @param tableNames 数据表名称...
     */
    public static void genCode(String... tableNames) throws IOException, TemplateException {
        Configuration cfg = getConfiguration(TEMPLATE_FILE_PATH);
        for (String tableName : tableNames) {
            Map<String, Object> data = getData(tableName);
            String modelNameUpperCamel = data.get("modelNameUpperCamel").toString();


            generateEntityParam(cfg, data, modelNameUpperCamel);
            generateEntityDto(cfg, data, modelNameUpperCamel);
//            getService(cfg, data, modelNameUpperCamel);
//            getServiceImpl(cfg, data, modelNameUpperCamel);
//            genManageController(cfg, data, modelNameUpperCamel);
        }
        //      generator(tableNames);
    }

    //===================================================== Vue Admin 基本增删改查接口 ===========================================================
    private static void getVueTable(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_VUE + "/views/" + modelNameUpperCamel + "/index.vue");
        createFilePath(file);
        cfg.getTemplate("vue-list.ftl").process(data, new FileWriter(file));
    }

    private static void getVueFrom(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_VUE + "/views/" + modelNameUpperCamel + "/components/" + modelNameUpperCamel + "Detail.vue");
        createFilePath(file);
        cfg.getTemplate("vue-form.ftl").process(data, new FileWriter(file));
    }

    private static void getVueUpdate(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_VUE + "/views/" + modelNameUpperCamel + "/update.vue");
        createFilePath(file);
        cfg.getTemplate("vue-update.ftl").process(data, new FileWriter(file));
    }

    private static void getVueAdd(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_VUE + "/views/" + modelNameUpperCamel + "/add.vue");
        createFilePath(file);
        cfg.getTemplate("vue-add.ftl").process(data, new FileWriter(file));
    }

    private static void getVueJs(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_VUE + "/js/" + modelNameUpperCamel + ".js");
        createFilePath(file);
        cfg.getTemplate("vue-js.ftl").process(data, new FileWriter(file));
    }

    //================================================== MyBatis-Plus CRUD接口 ====================================================================
    private static void getService(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_JAVA + packageConvertPath(BASE_PACKAGE) + "/service/" + modelNameUpperCamel + "Service.java");
        createFilePath(file);
        cfg.getTemplate("service.ftl").process(data, new FileWriter(file));
    }

    private static void getServiceImpl(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_JAVA + packageConvertPath(BASE_PACKAGE) + "/service/impl/" + modelNameUpperCamel + "ServiceImpl.java");
        createFilePath(file);
        cfg.getTemplate("serviceImpl.ftl").process(data, new FileWriter(file));
    }

    private static void genManageController(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_JAVA + packageConvertPath(BASE_PACKAGE) + "/controller/" + modelNameUpperCamel + "Controller.java");
        createFilePath(file);
        cfg.getTemplate("controller.ftl").process(data, new FileWriter(file));
    }

    //===========================================================实体类生成=============================================================================

    private static void generateEntityParam(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_JAVA + packageConvertPath(BASE_PACKAGE) + "/param/" + modelNameUpperCamel + "Param.java");
        createFilePath(file);
        cfg.getTemplate("entity-param.ftl").process(data, new FileWriter(file));
    }

    private static void generateEntityDto(Configuration cfg, Map<String, Object> data, String modelNameUpperCamel) throws IOException, TemplateException {
        File file = new File(PACKAGE_PATH_JAVA + packageConvertPath(BASE_PACKAGE) + "/dto/" + modelNameUpperCamel + "Dto.java");
        createFilePath(file);
        cfg.getTemplate("entity-dto.ftl").process(data, new FileWriter(file));
    }


    public static void createFilePath(File file) {
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
    }

    public static Configuration getConfiguration(String url) throws IOException {
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
        cfg.setDirectoryForTemplateLoading(new File(url));
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
        return cfg;
    }


}
